home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 15
/
CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso
/
CUCD
/
Graphics
/
MysticView
/
source
/
guigfx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-12-28
|
10KB
|
422 lines
/*********************************************************************
----------------------------------------------------------------------
$VER: guigfx.c 11.0
©1996 TEK neoscientists
Functions for scaling, color-adapting, and displaying
chunky graphics.
This is a simple interface between render.library
and graphics.library.
There will be a seperate library for this purpose, soon.
----------------------------------------------------------------------
*********************************************************************/
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "render/render.h"
#include "utility/tagitem.h"
#include "graphics/gfx.h"
#include "graphics/view.h"
#include "exec/memory.h"
#include "proto/render.h"
#include "proto/graphics.h"
#include "proto/exec.h"
#include "guigfx.h"
#include "global.h"
/*------------------------------------------------------------------*/
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define FREEVECPTR(a) if(a){FreeRenderVec(a);a=NULL;}
/*------------------------------------------------------------------*/
/*********************************************************************
----------------------------------------------------------------------
psm = CreatePenShareMap ( void )
create and set-up a pensharemap.
----------------------------------------------------------------------
*********************************************************************/
struct PenShareMap *CreatePenShareMap(void)
{
APTR rmh, histo;
struct PenShareMap *psm;
if (rmh = CreateRMHandler(RND_MemType,RMHTYPE_POOL,TAG_DONE))
{
if (psm = (struct PenShareMap *) AllocRenderVec(rmh,sizeof(struct PenShareMap)))
{
if (histo = CreateHistogram(RND_RMHandler,rmh,RND_HSType,HSTYPE_18BIT,TAG_DONE))
{
psm -> histogram = histo;
psm -> memhandler = rmh;
psm -> mainpalette = 0;
psm -> mainnumcolors = 0;
psm -> mainpentab = 0;
psm -> basepalette = 0;
psm -> basenumcolors = 0;
psm -> basepentab = 0;
return psm;
}
FreeRenderVec(psm);
}
DeleteRMHandler(rmh);
}
return NULL;
}
/********************************************************************/
/*********************************************************************
----------------------------------------------------------------------
RemapChunkyArray ( source,palette,dest,width,height,pensharemap )
remap a chunky array to an obtained pensharemap.
This is a tricky algorythm to render
a chunky image to a pensharemap.
----------------------------------------------------------------------
*********************************************************************/
void RemapChunkyArray ( UBYTE *source, APTR palette,
UWORD width, UWORD height, UBYTE *dest, struct PenShareMap *psm)
{
APTR realpalette;
int i;
ULONG rgb[3];
UBYTE pentab[256];
UBYTE indextab[256];
if(psm->colormap)
{
if(realpalette = CreatePalette(RND_HSType,HSTYPE_18BIT,TAG_DONE))
{
for(i=0; i<psm->mainnumcolors; ++i)
{
GetRGB32(psm->colormap,psm->mainpentab[i],1,rgb);
ImportPalette(realpalette,rgb,1,
RND_PaletteFormat,PALFMT_RGB32,
RND_FirstColor,i,
TAG_DONE);
indextab[i]=i;
}
CreatePenTable(indextab,psm->mainpalette,
psm->mainnumcolors,1,realpalette,pentab,
RND_PenTable,psm->mainpentab,TAG_DONE);
ConvertChunky( source,palette,width,height,dest,
psm->mainpalette,RND_PenTable,pentab,TAG_DONE );
DeletePalette(realpalette);
}
}
}
/*********************************************************************
----------------------------------------------------------------------
void ReleasePenTab ( pentab, colormap, numcolors )
(internal)
----------------------------------------------------------------------
*********************************************************************/
void ReleasePenTab ( UBYTE *pentab, struct ColorMap *cm, UWORD numcolors )
{
int i;
for(i=0; i<numcolors; ++i)
{
ReleasePen(cm,(ULONG)pentab[i]);
}
}
/*********************************************************************
----------------------------------------------------------------------
obtained = ObtainPenTab ( palette, colormap, pentab, numcolors, precision )
(internal)
----------------------------------------------------------------------
*********************************************************************/
BOOL ObtainPenTab ( APTR palette, struct ColorMap *cm, UBYTE *pentab,
UWORD numcolors, ULONG precision )
{
int i;
LONG pen;
ULONG rgb[3];
UWORD count = 0;
for(i=0; i < numcolors; ++i)
{
ExportPalette(palette,rgb, RND_PaletteFormat,PALFMT_RGB32,
RND_FirstColor,i,
RND_NumColors,1,
TAG_DONE);
pen = ObtainBestPen(cm,rgb[0],rgb[1],rgb[2],OBP_Precision,precision,TAG_DONE);
if (pen == -1)
{
ReleasePenTab(pentab,cm,count);
return FALSE;
}
else
{
pentab[i] = (UBYTE) pen;
count++;
}
}
return TRUE;
}
/*********************************************************************
----------------------------------------------------------------------
void ReleasePenShareMap ( psm )
release a pensharemap from its ColorMap.
----------------------------------------------------------------------
*********************************************************************/
void ReleasePenShareMap ( struct PenShareMap *psm )
{
if(psm->basenumcolors && psm->basepentab && psm->colormap)
{
ReleasePenTab(psm->basepentab,psm->colormap,psm->basenumcolors);
}
if(psm->mainnumcolors && psm->mainpentab && psm->colormap)
{
ReleasePenTab(psm->mainpentab,psm->colormap,psm->mainnumcolors);
}
FREEVECPTR(psm->mainpentab);
if(psm->mainpalette)
{
DeletePalette(psm->mainpalette);
psm->mainpalette = 0;
}
FREEVECPTR(psm->basepentab);
if(psm->basepalette)
{
DeletePalette(psm->basepalette);
psm->basepalette = 0;
}
psm->mainnumcolors = 0;
psm->basenumcolors = 0;
psm->colormap = NULL;
}
/*********************************************************************
----------------------------------------------------------------------
DeletePenShareMap(psm)
annihilate pensharemap (and release it, if obtained before).
----------------------------------------------------------------------
*********************************************************************/
void DeletePenShareMap(struct PenShareMap *psm)
{
APTR rmh = psm -> memhandler;
ReleasePenShareMap(psm);
DeleteHistogram(psm->histogram);
FreeRenderVec(psm);
DeleteRMHandler(rmh);
}
/*********************************************************************
----------------------------------------------------------------------
success = ObtainPenShareMap ( psm,colormap,precision )
obtain a pensharemap's colors from a ColorMap.
----------------------------------------------------------------------
*********************************************************************/
BOOL ObtainPenShareMap ( struct PenShareMap *psm, struct ColorMap *cm,
ULONG precision )
{
LONG baseColors, mainColors, histoColors;
struct PaletteExtra *pe;
UWORD numsharable = 0;
histoColors = QueryHistogram(psm->histogram,RND_NumColors);
if(histoColors < 1)
{
return FALSE;
}
mainColors = MIN(histoColors,256);
if (pe = cm->PalExtra)
{
ObtainSemaphoreShared(&pe->pe_Semaphore);
numsharable = pe->pe_NFree;
baseColors = (DOUBLE)sqrt((DOUBLE)numsharable*(DOUBLE)8.0);
ReleaseSemaphore(&pe->pe_Semaphore);
}
else
{
baseColors = 0;
}
baseColors = MIN(mainColors,baseColors);
if(baseColors > 0)
{
if(!(psm->basepalette = CreatePalette(RND_HSType,HSTYPE_18BIT,
RND_RMHandler,psm->memhandler,TAG_DONE)))
{
ReleasePenShareMap(psm);
return FALSE;
}
if(!(psm->basepentab = AllocRenderVec(psm->memhandler, baseColors)))
{
DeletePenShareMap(psm);
return FALSE;
}
}
if(!(psm->mainpalette = CreatePalette(RND_HSType,HSTYPE_18BIT,
RND_RMHandler,psm->memhandler,TAG_DONE)))
{
DeletePenShareMap(psm);
return FALSE;
}
if(!(psm->mainpentab = AllocRenderVec(psm->memhandler, mainColors)))
{
DeletePenShareMap(psm);
return FALSE;
}
if(numsharable < THRESHOLD_SPAREMODE)
{
if (baseColors > 0)
{
if (ExtractPalette(psm->histogram,psm->basepalette,baseColors,
RND_NewPalette,TRUE,TAG_DONE) != EXTP_SUCCESS)
{
DeletePenShareMap(psm);
return FALSE;
}
SortPalette(psm->basepalette,PALMODE_SIGNIFICANCE,
RND_Histogram,psm->histogram,TAG_DONE);
}
}
if (ExtractPalette(psm->histogram,psm->mainpalette,mainColors,
RND_NewPalette,TRUE,TAG_DONE) != EXTP_SUCCESS)
{
DeletePenShareMap(psm);
return FALSE;
}
SortPalette(psm->mainpalette,PALMODE_SIGNIFICANCE,
RND_Histogram,psm->histogram,TAG_DONE);
if(baseColors > 0)
{
if(ObtainPenTab(psm->basepalette,cm,psm->basepentab,baseColors,precision) == FALSE)
{
DeletePenShareMap(psm);
return FALSE;
}
}
if (ObtainPenTab(psm->mainpalette,cm,psm->mainpentab,mainColors,precision) == FALSE)
{
DeletePenShareMap(psm);
return FALSE;
}
psm->mainnumcolors = mainColors;
psm->basenumcolors = baseColors;
psm->colormap = cm;
return TRUE;
}
/*********************************************************************
----------------------------------------------------------------------
DrawChunkyArray ( rastport,array,x,y,width,height )
draw a chunky array to a rastport.
----------------------------------------------------------------------
*********************************************************************/
void DrawChunkyArray ( struct RastPort *rp, UBYTE *array, UWORD x,
UWORD y, UWORD width, UWORD height )
{
struct RastPort trp;
struct BitMap *tbm;
if (tbm = AllocBitMap(((width+15)>>4)<<4,1,rp->BitMap->Depth,0,rp->BitMap))
{
memcpy(&trp,rp,sizeof(struct RastPort));
trp.Layer = NULL;
trp.BitMap = tbm;
WritePixelArray8(rp,x,y,x+width-1,y+height-1,array,&trp);
FreeBitMap(tbm);
}
}